#include "StdAfx.h"

#include "../Vocoder/Settings.h"
#include "../Vocoder/Vocoder.h"
#include "../Vocoder/PerformanceMonitor.h"
#include "VocoderThread.h"
#include "PlayerThread.h"

VocoderThread::VocoderThread(void)
{
	isRunning = false;
}

VocoderThread::~VocoderThread(void)
{
}

void VocoderThread::Initialize(Modulator* modulator, Carrier* carrier, Vocoder* vocoder, PlayerThread* playerThread, PerformanceMonitor* performanceMonitor, unsigned int windowLength)
{
	this->modulator = modulator;
	this->carrier = carrier;
	this->vocoder = vocoder;
	this->playerThread = playerThread;
	this->performanceMonitor = performanceMonitor;
	this->windowLength = windowLength;
	modulatorBuf.resize(windowLength);
	carrierBuf.resize(windowLength);
	vocoderBuf.resize(windowLength);

	Launch();
}

void VocoderThread::Run()
{
    isRunning = true;
    while(isRunning)
    {
		bool moreModulatorSamples = modulator->NextModulatorSample(&(modulatorBuf[0]), windowLength, &sampleMarkers);
		performanceMonitor->ReceivedModulator(windowLength);
		short* carrierSample = carrier->CreateCarrierSample(vocoder->GetSettings(), &(modulatorBuf[0]), windowLength, &sampleMarkers);
		vocoder->Vocode(&(modulatorBuf[0]), carrierSample, &(vocoderBuf[0]), windowLength);
		performanceMonitor->ReceivedVocoded(windowLength);

		switch(vocoder->GetSettings()->GetPlayer()->streamType)
		{
		case Settings::PlayerSettings::StreamType::Carrier:
			playerThread->AddSamples(carrierSample, windowLength);
			break;
		case Settings::PlayerSettings::StreamType::Modulator:
			playerThread->AddSamples(&(modulatorBuf[0]), windowLength);
			break;
		case Settings::PlayerSettings::StreamType::Vocoder:
			playerThread->AddSamples(&(vocoderBuf[0]), windowLength);
			break;
		}

		if(!moreModulatorSamples)
		{
			playerThread->listener->OnStreamEnded();
		}		
	}
}

void VocoderThread::Stop()
{
	isRunning = false;
    Thread::Terminate();
}
